package com.yq.cp.service.data.impl;

import com.yq.cp.entity.data.dto.*;
import com.yq.cp.entity.data.vo.IndexDataByCompanyVo;
import com.yq.cp.entity.data.vo.IndexDataViewVo;
import com.yq.cp.entity.data.vo.IndexDayAllDataVo;
import com.yq.cp.mapper.data.NengKongDataDayMapper;
import com.yq.cp.service.data.IndexService;
import com.yq.cp.utils.DateTimeUtil;
import com.yq.cp.utils.UnitUtil;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

@Service
@Transactional
public class IndexServiceImpl implements IndexService {

    @Resource
    private NengKongDataDayMapper dataDayMapper;


    @Override
    public List<IndexDayAllDataDto> dayAllDate(IndexDayAllDataVo val) {
        //获取该时间的累计数据
        List<IndexDataSqlDto> dayAllData = dataDayMapper.getDayAllData(val.getDataTime(),val.getState(),1,val.getCompanyId());
        List<IndexDataSqlDto> dataList = createSqlList(dayAllData,val.getState());

        //获取该时间的实时数据
        List<IndexDataSqlDto> realTimeData = dataDayMapper.getDayAllData(val.getDataTime(), val.getState(), 2,val.getCompanyId());
        List<IndexDataSqlDto> realDataList = createSqlList(realTimeData,val.getState());

        //获取前一天数据计算环比
        //得到前一天的时间
        String dateBefore = DateTimeUtil.simpleDate(DateTimeUtil.getDateBefore(DateTimeUtil.toSimpleDate(val.getDataTime()), 1));
        List<IndexDataSqlDto> lastAllData = dataDayMapper.getDayAllData(dateBefore,val.getState(),1,val.getCompanyId());
        List<IndexDataSqlDto> lastDataList = createSqlList(lastAllData,val.getState());


        ArrayList<IndexDayAllDataDto> data = new ArrayList<>();
        //计算环比
        dataList.forEach(i ->{
            IndexDayAllDataDto dto = new IndexDayAllDataDto();
            //计算环比
            lastDataList.forEach(j ->{
                if (i.getType().compareTo(j.getType())==0){
                    //当昨天的数据为0时环比为0
                    //添加环比
                    if (j.getValue().compareTo(new BigDecimal(0))==0){
                        dto.setHb(0);
                    }else {
                        BigDecimal hb = i.getValue().subtract(j.getValue()).divide(j.getValue(), 2, BigDecimal.ROUND_CEILING).multiply(new BigDecimal(100.00));
                        dto.setHb(hb.intValue());
                    }
                }
            });
            //添加类型
            dto.setType(i.getType());
            //添加累计数据
            dto.setDayData(UnitUtil.unit(i.getValue(),i.getType()));
            //添加实时数据
            realDataList.forEach(o ->{
                if (i.getType().compareTo(o.getType())==0){
                    dto.setRealTimeData(UnitUtil.realUnit(o.getValue(),i.getType()));
                }
            });
            data.add(dto);
        });
        return data;
    }

    @Override
    public Map<String, Object> dataByCompany(IndexDataByCompanyVo val) {
        //获取日期
        Calendar calendar = Calendar.getInstance();
        String time = "";
        String lastTime = "";
        if (val.getTimeState()==1){
            //当日
            time = DateTimeUtil.today();
            //昨日
            lastTime = DateTimeUtil.simpleDate(DateTimeUtil.getDateBefore(DateTimeUtil.toSimpleDate(time), 1));
        }else if (val.getTimeState()==2){
            //当月
            int month = DateTimeUtil.getMonth();
            int year = DateTimeUtil.getYear();
            time = year+"-"+month+"-00";
            //上月
            month--;
            lastTime = year+"-"+month+"-00";
        }else if (val.getTimeState()==3){
            //当年
            int year = DateTimeUtil.getYear();
            time = year+"-00-00";
            //去年
            year--;
            lastTime = year+"-00-00";
        }


        List<IndexDataSqlByCompanyDto> dataList = new ArrayList<>();
        List<IndexDataSqlDto> allDataList = new ArrayList<>();
        List<IndexDataSqlDto> lastAllDataList = new ArrayList<>();
        //获取当前时间数据
        if (val.getCompanyId()==null){
            //说明为集团查询,查询所有公司的数据
            List<IndexDataSqlByCompanyDto> dataByCompany = dataDayMapper.getDataByCompany(val.getTimeState(), time, val.getState());
            dataList = createSqlCompanyList(dataByCompany, val.getState());
            //获取集团当前时间的总数据
            List<IndexDataSqlDto> allData = dataDayMapper.getAllDataByCompany(val.getTimeState(), time, val.getState());
            allDataList = createSqlList(allData, val.getState());
            //获取集团前一段时间的总数据
            List<IndexDataSqlDto> lastAllData = dataDayMapper.getAllDataByCompany(val.getTimeState(), lastTime, val.getState());
            lastAllDataList = createSqlList(lastAllData, val.getState());
        }else {
            //为查询公司旗下的能源站数据
            List<IndexDataSqlByCompanyDto> dataByEnergy = dataDayMapper.getDataByEnergy(val.getTimeState(), time, val.getState(), val.getCompanyId());
            dataList = createSqlCompanyList(dataByEnergy, val.getState());
            List<IndexDataSqlDto> allDataByEnergy = dataDayMapper.getAllDataByEnergy(val.getTimeState(), time, val.getState(), val.getCompanyId());
            allDataList = createSqlList(allDataByEnergy,val.getState());
            List<IndexDataSqlDto> lastAllData = dataDayMapper.getAllDataByEnergy(val.getTimeState(), lastTime, val.getState(), val.getCompanyId());
            lastAllDataList = createSqlList(lastAllData,val.getState());
        }
        //处理返回数据
        Map<String, Object> map = new HashMap<>();
        if (dataList==null || dataList.size()==0){
            map.put("companyData",new ArrayList<IndexDataByCompanyDto>());
        }else {
            List<IndexDataByCompanyDto> list = new ArrayList<>();
            dataList.forEach(o ->{
                IndexDataByCompanyDto data = new IndexDataByCompanyDto();
                data.setCompanyId(o.getCompanyId());
                data.setName(o.getName());
                List<IndexDayAllDataDto> dtolist = new ArrayList<>();
                o.getList().forEach(i ->{
                    dtolist.add(new IndexDayAllDataDto(i.getType(),UnitUtil.unit(i.getValue(),i.getType())));
                });
                data.setList(dtolist);
                list.add(data);
            });
            //各个公司数据
            map.put("companyData",list);
        }
        //处理环比
        ArrayList<IndexDayAllDataDto> data = new ArrayList<>();
        //计算环比和集团汇总
        List<IndexDataSqlDto> finalLastAllDataList = lastAllDataList;
        allDataList.forEach(i ->{
            IndexDayAllDataDto dto = new IndexDayAllDataDto();
            //计算环比
            finalLastAllDataList.forEach(j ->{
                if (i.getType().compareTo(j.getType())==0){
                    //当昨天的数据为0时环比为0
                    //添加环比
                    if (j.getValue().compareTo(new BigDecimal(0))==0){
                        dto.setHb(0);
                    }else {
                        BigDecimal hb = i.getValue().subtract(j.getValue()).divide(j.getValue(), 2, BigDecimal.ROUND_CEILING).multiply(new BigDecimal(100.00));
                        dto.setHb(hb.intValue());
                    }
                }
            });
            //添加类型
            dto.setType(i.getType());
            //添加累计数据
            dto.setDayData(UnitUtil.unit(i.getValue(),i.getType()));
            data.add(dto);
        });
        //公司总数据
        map.put("allCompnayData",data);

        return map;
    }

    @Override
    public List<IndexSqlDataViewDto> dataView(IndexDataViewVo val) {

        //获取数据
        List<IndexSqlDataViewDto> dataView = dataDayMapper.getDataView(val);
        //处理后的数据
        List<IndexSqlDataViewDto> list = createSqlViewList(dataView, val);
        return UnitUtil.unit2(list);

    }


    /**
     * 处理数据方法
     * @param dayAllData
     * @param state
     * @return
     */
    private List<IndexDataSqlDto> createSqlList(List<IndexDataSqlDto> dayAllData,Integer state){

        if (state==1){
            ArrayList<Integer> list = new ArrayList<>();
            list.add(100);
            list.add(101);
            list.add(102);
            list.add(103);
            //得到集合中的type
            List<Integer> types = dayAllData.stream().map(s -> s.getType()).collect(Collectors.toList());
            list.forEach(i ->{
                if (!types.contains(i)){
                    //说明没得该type的数据,需要手动添加数据为0的数据和type
                    dayAllData.add(new IndexDataSqlDto(i,new BigDecimal(0)));
                }
            });
        }else if (state==2){
            ArrayList<Integer> list = new ArrayList<>();
            list.add(200);
            list.add(201);
            list.add(202);
            list.add(203);
            list.add(204);
            //得到集合中的type
            List<Integer> types = dayAllData.stream().map(s -> s.getType()).collect(Collectors.toList());
            list.forEach(i ->{
                if (!types.contains(i)){
                    //说明没得该type的数据,需要手动添加数据为0的数据和type
                    dayAllData.add(new IndexDataSqlDto(i,new BigDecimal(0)));
                }
            });
        }else if (state==3){
            ArrayList<Integer> list = new ArrayList<>();
            list.add(300);
            list.add(301);
            list.add(302);
            list.add(303);
            list.add(304);
            //得到集合中的type
            List<Integer> types = dayAllData.stream().map(s -> s.getType()).collect(Collectors.toList());
            list.forEach(i ->{
                if (!types.contains(i)){
                    //说明没得该type的数据,需要手动添加数据为0的数据和type
                    dayAllData.add(new IndexDataSqlDto(i,new BigDecimal(0)));
                }
            });
        }

        return dayAllData;

    }


    /**
     * 处理公司数据方法
     * @param dayAllData
     * @param state
     * @return
     */
    private List<IndexDataSqlByCompanyDto> createSqlCompanyList(List<IndexDataSqlByCompanyDto> dayAllData,Integer state){
        if (dayAllData.size()==0){
            return null;
        }
        dayAllData.forEach(val ->{
            if (state==1){
                ArrayList<Integer> list = new ArrayList<>();
                list.add(100);
                list.add(101);
                list.add(102);
                list.add(103);
                //得到集合中的type
                List<Integer> types = val.getList().stream().map(s -> s.getType()).collect(Collectors.toList());
                list.forEach(i ->{
                    if (!types.contains(i)){
                        //说明没得该type的数据,需要手动添加数据为0的数据和type
                        List<IndexDataSqlDto> l = val.getList();
                        l.add(new IndexDataSqlDto(i,new BigDecimal(0)));
                        val.setList(l);
                    }
                });
            }else if (state==2){
                ArrayList<Integer> list = new ArrayList<>();
                list.add(200);
                list.add(201);
                list.add(202);
                list.add(203);
                list.add(204);
                //得到集合中的type
                List<Integer> types = val.getList().stream().map(s -> s.getType()).collect(Collectors.toList());
                list.forEach(i ->{
                    if (!types.contains(i)){
                        //说明没得该type的数据,需要手动添加数据为0的数据和type
                        List<IndexDataSqlDto> l = val.getList();
                        l.add(new IndexDataSqlDto(i,new BigDecimal(0)));
                        val.setList(l);
                    }
                });
            }
        });
        return dayAllData;
    }

    private List<IndexSqlDataViewDto> createSqlViewList(List<IndexSqlDataViewDto> dtoList,IndexDataViewVo val){
        List<String> timeList = new ArrayList<String>();
        //将时间范围内的每个时间点算出
        if (val.getStateTime()==1){
            //日耗
            timeList = DateTimeUtil.getTwoDaysDayDes(val.getStartTime(),val.getEndTime());
        }else if (val.getStateTime()==2){
            //月耗
            timeList = DateTimeUtil.getMonthBetweenDate(val.getStartTime(),val.getEndTime());
        }

        ArrayList<Integer> list1 = new ArrayList<>();
        list1.add(100);
        list1.add(101);
        list1.add(102);
        list1.add(103);
        ArrayList<Integer> list2 = new ArrayList<>();
        list2.add(200);
        list2.add(201);
        list2.add(202);
        list2.add(203);
        list2.add(204);

        List<IndexSqlDataViewDto> list = new ArrayList<>();

        timeList.forEach(i ->{
            boolean bool = true;
            if (dtoList==null | dtoList.size()==0){

            }else {
                for (IndexSqlDataViewDto o : dtoList) {
                    //时间相同说明有该时间的数据,判断数据是否完整
                    String tt = "";
                    if (val.getStateTime()==2){
                        tt = o.getTime().substring(0,o.getTime().length()-3);
                    }else {
                        tt = o.getTime();
                    }


                    if (i.equals(tt)) {
                        List<Integer> types = o.getList().stream().map(s -> s.getType()).collect(Collectors.toList());
                        ArrayList<Integer> iList = new ArrayList<>();
                        if (val.getState()==1){
                            iList = list1;
                        }else {
                            iList = list2;
                        }

                        iList.forEach(t -> {
                            if (!types.contains(t)) {
                                List<IndexDataSqlDto> oList = o.getList();
                                oList.add(new IndexDataSqlDto(t, new BigDecimal(0)));
                                o.setList(oList);
                            }
                        });
                        IndexSqlDataViewDto dto = new IndexSqlDataViewDto();
                        dto.setTime(i);
                        dto.setList(o.getList());
                        list.add(dto);
                        bool = false;
                    }
                }
            }

            if (bool){
                //说明bool没更改,没有找到时间相同的值,说明数据库的数据缺少时间
                List<IndexDataSqlDto> oList = new ArrayList<>();

                ArrayList<Integer> iList = new ArrayList<>();
                if (val.getState()==1){
                    iList = list1;
                }else {
                    iList = list2;
                }

                iList.forEach(t ->{
                    oList.add(new IndexDataSqlDto(t,new BigDecimal(0)));
                });
                IndexSqlDataViewDto dto = new IndexSqlDataViewDto();
                dto.setTime(i);
                dto.setList(oList);
                list.add(dto);
            }
        });
//        else if (val.getState()==2) {
//            timeList.forEach(i -> {
//                boolean bool = true;
//                for (IndexSqlDataViewDto o : dtoList) {
//                    //时间相同说明有该时间的数据,判断数据是否完整
//                    if (i.equals(o.getTime())) {
//                        List<Integer> types = o.getList().stream().map(s -> s.getType()).collect(Collectors.toList());
//                        list2.forEach(t -> {
//                            if (!types.contains(t)) {
//                                List<IndexDataSqlDto> oList = o.getList();
//                                oList.add(new IndexDataSqlDto(t, new BigDecimal(0)));
//                                o.setList(oList);
//                            }
//                        });
//                        IndexSqlDataViewDto dto = new IndexSqlDataViewDto();
//                        dto.setTime(i);
//                        dto.setList(o.getList());
//                        list.add(dto);
//                        bool = false;
//                    }
//                }
//                if (bool) {
//                    //说明bool没更改,没有找到时间相同的值,说明数据库的数据缺少时间
//                    List<IndexDataSqlDto> oList = new ArrayList<>();
//                    list2.forEach(t -> {
//                        oList.add(new IndexDataSqlDto(t, new BigDecimal(0)));
//                    });
//                    IndexSqlDataViewDto dto = new IndexSqlDataViewDto();
//                    dto.setTime(i);
//                    dto.setList(oList);
//                    list.add(dto);
//                }
//            });
//        }
        return list;
    }




}
